/*
 * Copyright (C) 2014 nohana, Inc.
 * Copyright 2017 Zhihu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.zhihu.matisse.utils;

import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.ResourceTable;
import com.zhihu.matisse.filter.Filter;
import com.zhihu.matisse.model.IncapableCause;
import com.zhihu.matisse.model.Item;
import com.zhihu.matisse.model.SelectionSpec;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.agp.utils.Point;
import ohos.app.Context;
import ohos.data.resultset.ResultSet;
import ohos.global.configuration.DeviceCapability;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import ohos.media.image.ImageSource;
import ohos.media.photokit.metadata.AVStorage;
import ohos.utils.net.Uri;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;

public final class PhotoMetadataUtils {
    private static final String TAG = PhotoMetadataUtils.class.getSimpleName();
    private static final int MAX_WIDTH = 1600;
    private static final String SCHEME_CONTENT = "content";

    private PhotoMetadataUtils() {
        throw new AssertionError("oops! the utility class is about to be instantiated...");
    }

    public static int getPixelsCount(DataAbilityHelper resolver, Uri uri) {
        Point size = getBitmapBound(resolver, uri);
        return (int) (size.getPointX() * size.getPointY());
    }

    public static Point getBitmapSize(Uri uri, Ability activity) {
        DataAbilityHelper resolver = DataAbilityHelper.creator(activity.getContext());
        Point imageSize = getBitmapBound(resolver, uri);
        int w = (int) imageSize.getPointX();
        int h = (int) imageSize.getPointY();

        if (h == 0) return new Point(MAX_WIDTH, MAX_WIDTH);

        DeviceCapability deviceCapability = activity.getResourceManager().getDeviceCapability();
        float screenWidth = (float) deviceCapability.width;
        float screenHeight = (float) deviceCapability.height;
        float widthScale = screenWidth / w;
        float heightScale = screenHeight / h;
        if (widthScale > heightScale) {
            return new Point((int) (w * widthScale), (int) (h * heightScale));
        }
        return new Point((int) (w * widthScale), (int) (h * heightScale));
    }

    public static Point getBitmapBound(DataAbilityHelper resolver, Uri uri) {
        InputStream is = null;
        try {
            is = new FileInputStream(resolver.openFile(uri,"r"));
            ImageSource.SourceOptions opts = new ImageSource.SourceOptions();
            ImageSource imageSource = ImageSource.create(is,opts);

            int width = imageSource.getImageInfo().size.width;
            int height = imageSource.getImageInfo().size.height;
            return new Point(width, height);
        } catch (FileNotFoundException e) {
            return new Point(0, 0);
        } catch (DataAbilityRemoteException e) {
            return new Point(0, 0);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    L.d(e.getMessage());
                }
            }
        }
    }

    public static String getPath(DataAbilityHelper resolver, Uri uri) {
        if (uri == null) {
            return null;
        }

        if (SCHEME_CONTENT.equals(uri.getScheme())) {
            ResultSet cursor = null;
            try {
                cursor = resolver.query(uri, new String[]{AVStorage.Images.Media.DATA},
                        null);
                if (cursor == null || !cursor.goToFirstRow()) {
                    return null;
                }
                return cursor.getString(cursor.getColumnIndexForName(AVStorage.Images.Media.DATA));
            } catch (DataAbilityRemoteException e) {

                return uri.getDecodedPath();
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }
        }
        return uri.getDecodedPath();
    }

    public static IncapableCause isAcceptable(Context context, Item item) {
        if (!isSelectableType(context, item)) {
            try {
                return new IncapableCause(context.getResourceManager().getElement(ResourceTable.String_error_file_type).getString());
            } catch (IOException | NotExistException | WrongTypeException e) {
                return new IncapableCause("Unsupported file type");
            }
        }

        if (SelectionSpec.getInstance().filters != null) {
            for (Filter filter : SelectionSpec.getInstance().filters) {
                IncapableCause incapableCause = filter.filter(context, item);
                if (incapableCause != null) {
                    return incapableCause;
                }
            }
        }
        return null;
    }

    private static boolean isSelectableType(Context context, Item item) {
        if (context == null) {
            return false;
        }

        DataAbilityHelper resolver = DataAbilityHelper.creator(context);
        for (MimeType type : SelectionSpec.getInstance().mimeTypeSet) {
            if (type.checkType(resolver, item.getContentUri())) {
                return true;
            }
        }
        return false;
    }

    public static float getSizeInMB(long sizeInBytes) {
        DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
        df.applyPattern("0.0");
        String result = df.format((float) sizeInBytes / 1024 / 1024);
        result = result.replaceAll(",", "."); // in some case , 0.0 will be 0,0
        return Float.parseFloat(result);
    }
}
